\begin{section}{Apéndices}

\begin{subsection}{Apéndice A - Enunciado} % Enunciado

\begin{centering}
\bf Laboratorio de M\'etodos Num\'ericos - Primer cuatrimestre 2011 \\
\bf Trabajo Pr\'actico N\'umero 1: Errores en serie ... \\
\end{centering}

\vskip 25pt
\hrule
\vskip 11pt

El objetivo del trabajo pr\'actico es analizar el comportamiento num\'erico de varios m\'etodos para aproximar $\pi$ cuando cada m\'etodo se implementa por medio de una aritm\'etica finita de $t$ d\'igitos. Los m\'etodos consisten en evaluar las siguientes series hasta un cierto t\'ermino:
\begin{description}
    \item[Serie de Gregory (1671):]
      \begin{equation*}
      \frac{\pi}{4} = \sum_{n=0}^{\infty} \frac{\left(-1\right)^n}{2n+1}
      \end{equation*}
    \item[F\'ormula de Machin (1706):]
      \begin{equation*}
      \frac{\pi}{4} = 4 \; \mathrm{arctan}(1/5) - \mathrm{arctan}(1/239), \qquad \text{con } \mathrm{arctan}(x) = \sum_{n=0}^{\infty} \left(-1\right)^n \frac{x^{2n+1}}{2n+1} \quad \text{cuando } \left|x\right|<1
      \end{equation*}
    \item[Serie de Ramanujan (1914):]
      \begin{equation*}
      \frac{1}{\pi} = \frac{\sqrt{8}}{9801} \sum_{n=0}^{\infty} \frac{(4n)! \, (1103 + 26390 n)}{(n!)^4 \, 396^{4n}}
      \end{equation*}
\end{description}

El trabajo pr\'actico consta de dos partes:
\vspace{-6pt}
\begin{enumerate}
 \item {\bf An\'alisis te\'orico} \label{punto1}

%     Analizar cada m\'etodo utilizando la f\'ormula del error, tomando en cuenta el error cometido en las operaciones debido a la representaci\'on finita de la aritm\'etica. Graficar la cota de error obtenida en cada caso en funci\'on de la cantidad de d\'igitos utilizados en la representaci\'on.

    Analizar la propagaci\'on de errores en el tercer t\'ermino (en funci\'on de los errores de los dos primeros) de cada una de las series propuestas, en funci\'on de la precisi\'on aritm\'etica utilizada. Emplear estos resultados en la argumentaci\'on de sus conclusiones luego de realizar el an\'alisis emp\'irico del punto 2.
    %~ ~\ref{punto2}.

 \item {\bf An\'alisis emp\'irico} \label{punto2}

    Implementar los tres m\'etodos con aritm\'etica binaria de punto flotante con $t$ d\'igitos de precisi\'on en la mantisa (el valor $t$ debe ser un par\'ametro de la implementaci\'on, $t < 52$) y comparar los errores relativos de los resultados obtenidos en los tres casos y con las cotas de error del punto anterior. Realizar al menos los siguientes experimentos num\'ericos:
    \begin{enumerate}
    \item Reportar el error relativo de cada m\'etodo en funci\'on de la cantidad de d\'igitos $t$ de precisi\'on en la mantisa, para cantidades fijas de t\'erminos $n$ de la serie.
    \item Reportar el error relativo de cada m\'etodo en funci\'on de la cantidad de t\'erminos $n$ de la serie correspondiente, para cantidad de d\'igitos $t$ de precisi\'on.
    \item Comparar los resultados obtenidos en \textit{a}) y \textit{b}) con las cotas de error calculadas en el punto~\ref{punto1}.
    %no uso \label + \ref porque me pone 2a 2b y ocupa demasiado
    \item (Opcional) Explorar distintas formas de implementar las f\'ormulas (realizar las cuentas) de cada cada m\'etodo.
    % Explorar distintas formas de evaluar cada m\'etodo.
    \end{enumerate}

    Se deben presentar los resultados de estas pruebas en un formato conveniente para su visualizaci\'on y an\'alisis.
    Sobre la base de los resultados obtenidos, ?`se pueden extraer conclusiones sobre la conveniencia de utilizar uno u otro m\'etodo?
\end{enumerate}

\vskip 15pt
\hrule
\vskip 11pt

{\bf Entregas parciales}
\vspace{-7pt}
\begin{description}
  \setlength{\itemsep}{0pt}
  \setlength{\parskip}{0pt}
  \setlength{\parsep}{0pt}
 \item[1 de abril:] An\'alisis te\'orico del error de los m\'etodos. Implementaci\'on b\'asica usando \texttt{float} y \texttt{double}.
 \item[8 de abril:] Implementaci\'on de los m\'etodos en aritm\'etica finita de $t$ d\'igitos. Resultados preliminares.
\end{description}

{\bf Entrega Final}
\vspace{-7pt}
\begin{description}
  \setlength{\itemsep}{0pt}
  \setlength{\parskip}{0pt}
  \setlength{\parsep}{0pt}
 \item[Formato Electr\'onico:] 14 de abril de 2011, hasta las 23:59 hs, a la direcci\'on: 

  {\emph{metnum.lab2011@gmail.com}}
 \item[Formato f\'isico:] 15 de abril de 2011, de 17 a 21 hs.
\end{description}


\end{subsection}

\begin{subsection}{Apéndice B - Código} % Código fuente relevante y algunos resultados específicos
%~ \newpage
\begin{subsubsection}{Clase Float}
\begin{lstlisting}[title={Clase Float}]
/* Esta clase provee aritmetica finita de t digitos. */
/* Interfaz. */

#ifndef FLOAT_H_
#define FLOAT_H_

#include <iostream>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <math.h>
using namespace std;

class Float 
{
        public:
                /* Constructor. */
                Float();
                /* Constructor. Recibe la precision deseada y un valor en double. */
                Float(int precision, long double value);
                /* Destructor. */
                ~Float();
                
                const int		exponent() 	const;
                const string		mantissa() 	const;
                const int		precision() 	const;
                const long double 	value()  	const;
                const long double 	absValue() 	const;
                
                /* Operadores. */                
                Float operator+ (Float f);
                Float operator- (Float f);
                Float operator/ (Float f);
                Float operator* (Float f);
                Float operator^ (Float f);
                
                /* Asignacion. */
                Float & operator= (const Float &);                              
                
        private:                              
                bool 		_isNeg;		/* Es negativo? */
                int 		_exponent;
                int 		_precision;	/* Cantidad de bits. */
                string 		_mantissa;	/* En binario. */
                long double 	_value;
                
                /* Funciones auxiliares de conversion entre tipos. */
                void 		longDoubleToBinary(long double);
                long double 	binaryToLongDouble();
};

#endif /*FLOAT_H_*/



/* Implementacion. */
#include "float.h"

Float::Float()
{	
}

Float::Float(int precision, long double value)
{
	_precision 	= precision;
	_mantissa 	= "";
	longDoubleToBinary(value);
	_value = binaryToLongDouble();
}

Float::~Float()
{
	
}

const int Float::exponent() const
{
	return _exponent;	
}

const string Float::mantissa() 	const
{
	return _mantissa;
}

const int Float::precision() const
{
	return _precision;
}

const long double Float::value() const
{
	return _value;
}

const long double Float::absValue() const
{
	if (_value < 0)
		return 0 - _value;
	else
		return _value;
}



Float Float::operator+ (Float f)
{
	long double result = _value + f.value();
	return Float(_precision, result);
}

Float Float::operator- (Float f)
{
	long double result = _value - f.value();
	return Float(_precision, result);
}

Float Float::operator/ (Float f)
{
	long double result = _value / f.value();
	return Float(_precision, result);
}

Float Float::operator* (Float f)
{
	long double result = _value * f.value();
	return Float(_precision, result);
}

Float Float::operator^ (Float f)
{
	long double result = pow(_value, f.value());
	return Float(_precision, result);
}

Float& Float::operator= (const Float& f)
{
	if (this == &f) 
		return *this;
		
	_precision 	= f.precision();
	_value 		= f.value();
	_exponent 	= f.exponent();
	_mantissa 	= f.mantissa();
	return *this;	
}

void Float::longDoubleToBinary(long double value)
{
	int sizeMantisa = _precision;
	long double mant;
		
	_isNeg = (value < 0);
	int exp = 0;
	
	/* Tomar el valor absoluto.*/
	if (_isNeg)  
		mant = ((-1) * value);
	else
		mant = value;
	
	
	
	/* Se busca la mantisa y se normaliza. */	
	while (mant >= 1)
	{
		mant /= 2;
        exp++;        
	}

	while (mant < 0.5 && mant != 0) 
	{
		mant *= 2;
        exp--;
	}

	_exponent = exp;
	
	while (mant > 0 && sizeMantisa > 0) 
	{
		mant *= 2;
		
        if (mant >= 1) 
        {
			_mantissa += "1";
			mant 	  -= 1;
        } 
        else       
			_mantissa += "0";
		
		sizeMantisa--;
    }
	
	while (sizeMantisa > 0) 
	{
		_mantissa += "0";
		sizeMantisa--;
	}	
}

long double Float::binaryToLongDouble()
{
	long double result, suma, aux;
	suma = 0;
	result = pow(2.0, (double)_exponent);	
	
	string bit;
	
	for(int i = 0; (unsigned int) i < _mantissa.size(); i++) 
	{
		bit 	=  _mantissa[i];
		aux 	= pow(2.0, (double)(-i-1));
		suma 	+= (atoi(bit.c_str()) * aux);
	}
	
	if (_isNeg) 	
		return (-1)*(result * suma);
	else
		return (result * suma);
}

\end{lstlisting}
\end{subsubsection}

\newpage
\begin{subsubsection}{Main}
\begin{lstlisting}[title={Main}]
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <math.h>
#include "float.h"

using namespace std;

int t;	/* Precision. */

/* Primer Metodo */
Float Gregory(int n)
{
    Float r = Float (t, 0); /* Resultado */
    Float a;
    
    for (int i = 0; i <= n; i++)
    {
        a = Float(t, 2*i + 1);
        
        if (i % 2 == 0)
			r = r + Float(t, 1.0)/a;
		else
			r = r - Float(t, 1.0)/a;
    }
        
    return r;
}

/* Segundo Metodo */
Float arctan(int n, Float x)
{
    Float r = Float (t, 0); /* Resultado */
    Float aux, a, b;    
    
    for (int i = 0; i <= n; i++)
    {
        aux = Float(t, 2*i + 1);
        a 	= Float(t, 1.0)/aux;
        b 	= x^aux;
        
        if (i % 2 == 0)
			r = r + (a * b);
		else
			r = r - (a * b);
    }
    
    return r;
}



Float factorial(int n)
{
	Float res = Float(t, 1);
	
	for (int i = 2; i <= n; i++)	
		res = res * Float(t, i);
	
	return res;
}

/* Tercer Metodo */
Float Ramanujan(int n)
{
    Float r = Float(t, 0); /* Resultado */
    Float a, b, c, d;
    
    for (int i = 0; i <= n; i++)
    {
        a = factorial(4*i); 
        b = Float(t, 1103.0 + 26390.0 * i);
        c = factorial(i) ^ Float(t, 4.0);
        d = Float(t, 396.0) ^ Float(t, 4*i);      
        
        r = r + ((a * b) / (c * d));
 
    }
    
    return r;
}

long double err(long double aprox, long double real)
{
	return fabs(aprox - real)/fabs(real);
}


int main()
{	
	ifstream entrada	("Casos.in");
	ofstream salida1	("G.out");
	ofstream salida2	("M.out");
	ofstream salida3	("R.out");
	
	int casos, n1, n2, n3;
	entrada >> casos;	
	
	while (casos != 0) 
	{
		entrada >> t;
		Float pi = Float(t, 3.1415926535897932384626433832795028841971693993751058209749);
		
		salida1.precision(t);
		salida2.precision(t);
		salida3.precision(t);
		
		Float res;
		/* Corro primer metodo. */
		entrada >> n1;
		res = Gregory(n1);
		res = res * Float(t, 4.0);	
		/* Precision, n, resultado, error relativo. */
		salida1 << t << "  " << n1 << " ";
		salida1 << res.value() << "     "; 
		salida1 << err(res.value(), pi.value()) << endl;
		
		/* Corro segundo metodo. */
		entrada >> n2;
		Float a = Float(t, 0.2);
		Float b = Float(t, 1.0) / Float(t, 239.0);
    		res = Float(t, 4.0)*arctan(n2, a) - arctan(n2, b);
		res = res * Float(t, 4.0);	
		/* Precision, n, resultado, error relativo. */
		salida2 << t << "  " << n2 << " ";
		salida2 << res.value() << "     "; 
		salida2 << err(res.value(), pi.value()) << endl;
				
		/* Corro tercer metodo. */
		entrada >> n3;
		res = (Float(t, sqrt(8)) / Float(t, 9801.0)) * Ramanujan(n3);
		res = Float(t, 1.0) / res;
		/* Precision, n, resultado, error relativo. */
		salida3 << t << "  " << n3 << " ";
		salida3 << res.value() << "     "; 
		salida3 << err(res.value(), pi.value()) << endl;
		
		casos --;
	}
	
    return 0;
}

\end{lstlisting}
\end{subsubsection}

\end{subsection}

%~ \newpage
\begin{subsection}{Imágenes}
\label{imagenes}
%~ \begin{figure}[H] \centering
	%~ \subfloat{\includegraphics[scale=0.3]{./otros/Ramanujan.png}}	
	%~ \hspace{10pt}
	%~ \subfloat{\includegraphics[scale=0.3]{./otros/Ramanujan2.png}}	
	%~ \caption{Ramanujan}
%~ \end{figure}
%~ \begin{figure}[H] %\centering
	%~ \subfloat{\includegraphics[scale=0.18]{./otros/Borg_Cube.png}}	
	%~ \hspace{10pt}
	%~ \subfloat{\includegraphics[scale=0.4]{./otros/Borg.png}}	
	%~ \caption{Borg}
%~ \end{figure}

%~ \begin{verbatim}
%~ / We are the Borg. Lower your shields and \
%~ | surrender your ships. You will be       |
%~ | asimilated. Your biological and         |
%~ | technological distinctiveness will be   |
%~ \ added to our own. Resistance is futile. /
 %~ -----------------------------------------
        %~ \   ^__^
         %~ \  (==)\_______
            %~ (__)\       )\/\
                %~ ||----w |
                %~ ||     ||
						%~ 
                         %~ by cowsay
%~ \end{verbatim}

%~ \begin{figure}[H] \centering
	%~ \subfloat{\includegraphics[scale=0.18]{./otros/Pi.png}}	
	%~ \hspace{10pt}
	%~ \subfloat{\includegraphics[scale=0.45]{./otros/Pi_Bird.png}}	
	%~ \caption{Pi}
%~ \end{figure}

\begin{figure}[H] \centering
	\subfloat{\includegraphics[scale=0.3]{./otros/Ramanujan.png}}	
	\caption{Ramanujan}
\end{figure}

\end{subsection}


\end{section}
